package com.liqi.frame.comm.session;

import cn.hutool.core.util.StrUtil;
import com.liqi.frame.comm.enums.OnlineStatusEnum;
import com.liqi.frame.comm.po.UserOnline;
import com.liqi.frame.comm.service.UserOnlineService;
import com.liqi.frame.comm.task.AsyncFactory;
import com.liqi.frame.comm.task.AsyncManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import java.io.Serializable;
import java.util.Date;
import java.util.Objects;

/**
 * @author liqi on 2020/1/21 0021. liqiwork@qq.com
 */
public class OnlineSessionDAO extends EnterpriseCacheSessionDAO {
    @Autowired
    private UserOnlineService userOnlineService;
    /**
     * 同步session到数据库的周期 单位为毫秒（默认1分钟）
     */
    @Value("${shiro.session.dbSyncPeriod}")
    private int dbSyncPeriod;

    private static final String LAST_SYNC_DB_TIMESTAMP = "LAST_SESSION_SYNC_DB_TIMESTAMP";

    /**
     * 根据会话ID获取会话
     *
     * @param sessionId 会话ID
     * @return ShiroSession
     */
    @Override
    protected Session doReadSession(Serializable sessionId) {

        Session session = userOnlineService.getSession(sessionId+"");
        return session;
//        if (Objects.isNull(session)) {
//            return null;
//        } else {
//            return createSession(session);
//        }
    }

//    public Session createSession(OnlineSession userOnline) {
//        OnlineSession onlineSession = new OnlineSession();
//        if (Objects.isNull(userOnline)) {
//            onlineSession.setId(userOnline.getId());
//            onlineSession.setHost(userOnline.getIpaddr());
//            onlineSession.setBrowser(userOnline.getBrowser());
//            onlineSession.setOs(userOnline.getOs());
//            onlineSession.setLoginName(userOnline.getFullname());
//            onlineSession.setStartTimestamp(userOnline.getStartTime());
//            onlineSession.setLastAccessTime(userOnline.getLastAccessTime());
//            onlineSession.setTimeout(userOnline.getExpireTime());
//        }
//        return onlineSession;
//    }

    /**
     * 当会话过期/停止（如用户退出时）属性等会调用
     */
    @Override
    protected void doDelete(Session session) {
        OnlineSession onlineSession = (OnlineSession) session;
        if (null == onlineSession) {
            return;
        }
        onlineSession.setStatus(OnlineStatusEnum.OFFLINE.getKey());
        userOnlineService.deleteSession(onlineSession);
    }

    public void syncToDb(OnlineSession onlineSession) {
        Date lastSyncTimestamp = (Date) onlineSession.getAttribute(LAST_SYNC_DB_TIMESTAMP);
        if (lastSyncTimestamp != null) {
            boolean needSync = true;
            long deltaTime = onlineSession.getLastAccessTime().getTime() - lastSyncTimestamp.getTime();
            if (deltaTime < dbSyncPeriod * 60 * 1000) {
                // 时间差不足 无需同步
                needSync = false;
            }
            // isGuest = true 访客
            boolean isGuest = onlineSession.getUserId() == null;

            // session 数据变更了 同步
            if (isGuest == false && onlineSession.isAttributeChanged()) {
                needSync = true;
            }

            if (needSync == false) {
                return;
            }
        }
        // 更新上次同步数据库时间
        onlineSession.setAttribute(LAST_SYNC_DB_TIMESTAMP, onlineSession.getLastAccessTime());
        // 更新完后 重置标识
        if (onlineSession.isAttributeChanged()) {
            onlineSession.resetAttributeChanged();
        }
        AsyncManager.me().execute(AsyncFactory.syncSessionToDb(onlineSession));
    }
}
